package com.yuandian.bpm.bi.modules.email.service.impl;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.yuandian.bpm.bi.modules.customs.sevice.CustomReportService;
import com.yuandian.bpm.bi.modules.email.entity.EmailInfo;
import com.yuandian.bpm.bi.modules.email.service.EmailService;
import com.yuandian.bpm.bi.modules.quartz.vo.ConfReportTaskInfo;
import com.yuandian.bpm.bi.modules.user.entity.ConfAddresser;
import com.yuandian.bpm.bi.modules.user.service.ConfAddresserService;
import com.yuandian.bpm.common.core.util.R;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.activation.DataHandler;
import javax.activation.FileDataSource;
import javax.mail.*;
import javax.mail.internet.*;
import java.io.File;
import java.io.UnsupportedEncodingException;
import java.sql.Wrapper;
import java.util.*;

@Service
public class EmailServiceImpl implements EmailService {

	Logger logger = LoggerFactory.getLogger(EmailServiceImpl.class);
	/**
	 * 当前应用程序，启动目录
	 */
	private final String user_path = "user.dir";
	/**
	 * 文档生成存放路径名称
	 */
	private final String doc_path = "docs";
	/**
	 * 文档生成存放基础路径
	 */
	private final String basePath = System.getProperty(user_path) + File.separator + doc_path;
	@Autowired
	ConfAddresserService confAddresserService;
	@Autowired
	CustomReportService customReportService;

	@Override
	public R<String> sendEmail(EmailInfo emailInfo) {

		Properties properties = new Properties();
		properties.put("mail.smtp.host", emailInfo.getHost());
		properties.put("mail.smtp.auth", "true");
		Session session = Session.getInstance(properties);
		Message emailMessage = new MimeMessage(session);

		try {
			//发送人
			InternetAddress sender = new InternetAddress(emailInfo.getFrom()); //发送者账号
			String nickname = emailInfo.getNickname();
			if (ObjectUtil.isNotEmpty(nickname)) {
				sender.setPersonal(MimeUtility.encodeText(nickname));//昵称
			}

			emailMessage.setFrom(sender);

			//收件人
			List<String> address = emailInfo.getAddress();
			if (ObjectUtil.isNotEmpty(address)) {
				emailMessage.setRecipients(Message.RecipientType.TO, toAddress(address));
			}


			//抄送
			List<String> ccRecipients = emailInfo.getCcRecipients();
			if (ObjectUtil.isNotEmpty(ccRecipients)) {
				emailMessage.setRecipients(Message.RecipientType.CC, toAddress(ccRecipients));
			}
			//密送
			List<String> bccRecipients = emailInfo.getBccRecipients();
			if (ObjectUtil.isNotEmpty(bccRecipients)) {
				emailMessage.setRecipients(Message.RecipientType.BCC, toAddress(bccRecipients));
			}
			//消息
			emailMessage.setSubject(MimeUtility.encodeText(emailInfo.getSubject()));//邮件主题
			emailMessage.setSentDate(new Date());
			MimeMultipart mimeMultipart = new MimeMultipart("mixed");//指定为混合关系
			emailMessage.setContent(mimeMultipart);

			//邮件内容
			MimeBodyPart htmlPart = new MimeBodyPart();
			htmlPart.setContent(emailInfo.getContent(), "text/html;charset=UTF-8");

			//组装内容
			mimeMultipart.addBodyPart(htmlPart);

			//组装附件
			String filePath = emailInfo.getFilePath();
			if (null != filePath && !"".equals(filePath)) {
				filePath = basePath + File.separator + filePath;
				if (filePath.indexOf("|") < 0) {
					boolean exist = FileUtil.exist(filePath);
					if (!exist) {
						logger.error("文件：{}不存在！", filePath);
					}
					MimeBodyPart file = new MimeBodyPart();
					FileDataSource file_datasource = new FileDataSource(filePath);
					DataHandler dh = new DataHandler(file_datasource);
					file.setDataHandler(dh);
					//附件区别内嵌内容的一个特点是有文件名，为防止中文乱码要编码
					file.setFileName(MimeUtility.encodeText(dh.getName()));
					mimeMultipart.addBodyPart(file);
				} else {
					String[] filePaths = filePath.split("\\|");
					for (int i = 0; i < filePaths.length; i++) {
						boolean exist = FileUtil.exist(basePath + File.separator + filePaths[i]);
						if (!exist) {
							logger.error("文件：{}不存在！", basePath + File.separator + filePaths[i]);
						}
						MimeBodyPart file = new MimeBodyPart();
						FileDataSource file_datasource = new FileDataSource(basePath + File.separator + filePaths[i]);
						DataHandler dh = new DataHandler(file_datasource);
						file.setDataHandler(dh);
						//附件区别内嵌内容的一个特点是有文件名，为防止中文乱码要编码
						file.setFileName(MimeUtility.encodeText(dh.getName()));
						mimeMultipart.addBodyPart(file);
					}
				}
			}

			emailMessage.saveChanges();
			Transport transport = session.getTransport("smtp");
			transport.connect(emailInfo.getHost(), Integer.parseInt(emailInfo.getPort()), emailInfo.getFrom(), emailInfo.getPassword());
			transport.sendMessage(emailMessage, emailMessage.getAllRecipients());
			transport.close();
			return R.ok("邮件发送成功！");
		} catch (AddressException e) {
			logger.error("邮件发送失败，错误原因：" + e.getMessage());
			return R.failed("请检查邮箱地址:" + e.getMessage());
		} catch (UnsupportedEncodingException e) {
			logger.error("邮件发送失败，错误原因：" + e.getMessage());
			return R.failed("转码异常，请查看详细信息" + e.getMessage());
		} catch (NoSuchProviderException e) {
			logger.error("邮件发送失败，错误原因：" + e.getMessage());
			return R.failed("邮件发送失败，详细错误原因：" + e.getMessage());
		} catch (MessagingException e) {
			logger.error("邮件发送失败，错误原因：" + e.getMessage());
			return R.failed("邮件发送失败，有可能的问题为服务器url不存在或附件不存在，具体请看详细信息：" + e.getMessage());
		}
	}

	@Override
	public R<String> sendEmailHandle(ConfReportTaskInfo confReportTaskInfo) {

		EmailInfo emailInfo = new EmailInfo();
		emailInfo.setFilePath(confReportTaskInfo.getReportFileName());
		//发件人
		String emailSender = confReportTaskInfo.getEmailSender();
		ConfAddresser addresser = confAddresserService.getById(emailSender);
		if (ObjectUtil.isEmpty(addresser)) {
			QueryWrapper<ConfAddresser> wrapper = new QueryWrapper<>();
			wrapper.eq("is_default", 1);
			addresser = confAddresserService.getOne(wrapper);
		}
		if(ObjectUtil.isEmpty(addresser)){
			logger.error("未找到发件人！");
			return R.failed("未找到发件人,请进行配置！");
		}
		String emailRecipient = confReportTaskInfo.getEmailRecipient();
		String emailRecipientCustom = confReportTaskInfo.getEmailRecipientCustom();
		List<String> list = new ArrayList<>();
		//收件人----------> 开始
		if (ObjectUtil.isEmpty(emailRecipient)) {
			List<String> emailRecipients = Arrays.asList(emailRecipient.split(","));
			list.addAll(emailRecipients);
		}
		//自定义收件人
		if(ObjectUtil.isNotEmpty(emailRecipientCustom)){
			List<String> emailRecipientCustoms = Arrays.asList(emailRecipientCustom.split(","));
			list.addAll(emailRecipientCustoms);
		}
		emailInfo.setAddress(list);
		//收件人----------> 结束
		//抄送人----------> 开始
		List emailCcs = new ArrayList();
		String emailCcBy = confReportTaskInfo.getEmailCcBy();
		if (ObjectUtil.isNotEmpty(emailCcBy)) {
			List<String> tepmCc = Arrays.asList(emailCcBy.split(","));
			emailCcs.addAll(tepmCc);
		}
		//自定义抄送人
		String emailCcByCustom = confReportTaskInfo.getEmailCcByCustom();
		if(ObjectUtil.isNotEmpty(emailCcByCustom)){
			emailCcs.addAll(Arrays.asList(emailCcByCustom.split(",")));
		}
		emailInfo.setCcRecipients(emailCcs);
		//抄送人----------> 结束
		//密送人----------> 开始
		List<String> bccs = new ArrayList<>();
		String emailBccRecipient = confReportTaskInfo.getEmailBccRecipient();
		if (ObjectUtil.isNotEmpty(emailBccRecipient)) {
			bccs.addAll(Arrays.asList(emailBccRecipient.split(",")));
		}
		//自定义密送人
		String emailBccRecipientCustom = confReportTaskInfo.getEmailBccRecipientCustom();
		if(ObjectUtil.isNotEmpty(emailBccRecipientCustom)){
			bccs.addAll(Arrays.asList(emailBccRecipientCustom.split(",")));
		}
		emailInfo.setBccRecipients(bccs);
		//密送人----------> 结束
		if(ObjectUtil.isEmpty(list) && ObjectUtil.isEmpty(bccs)){
			logger.error("未找到收件人！");
			return R.failed("未找到收件人,请进行配置！");
		}
		Integer emailBodyLinkFlag = confReportTaskInfo.getEmailBodyLinkFlag();
		String emailContent = confReportTaskInfo.getEmailContent();

		if(emailBodyLinkFlag != null && emailBodyLinkFlag.equals(1)){
			String previewUrl = customReportService.getPreviewUrl(confReportTaskInfo.getReportTemplateId());
			emailContent = emailContent + "报表预览链接：" +previewUrl;
		}
		emailInfo.setContent(emailContent);//邮件内容
		emailInfo.setHost(addresser.getEmailHost());//邮件服务器
		emailInfo.setPort(addresser.getEmailPort().toString());//邮件端口
		emailInfo.setSubject(confReportTaskInfo.getEmailSubject());//邮件主题
		emailInfo.setFrom(addresser.getEmail());//发件人
		emailInfo.setPassword(addresser.getPassword());//授权码
		Integer emailAttachmentFlag = confReportTaskInfo.getEmailAttachmentFlag();
		if(emailAttachmentFlag != null && emailAttachmentFlag == 1){//邮件使用附件
			emailInfo.setFilePath(confReportTaskInfo.getReportFileName());
		}
		return sendEmail(emailInfo);
	}

	@Override
	public R sendTestmail(String address, Integer senderId) {
		ConfAddresser addresser = confAddresserService.getById(senderId);
		EmailInfo emailInfo = new EmailInfo();
		List<String> list = new ArrayList<>();
		list.add(address);
		emailInfo.setAddress(list);
		emailInfo.setContent("恭喜您！您的邮件服务器已经配置成功!");
		emailInfo.setHost(addresser.getEmailHost());
		emailInfo.setPort(addresser.getEmailPort().toString());
		emailInfo.setSubject("邮件测试");
		emailInfo.setFrom(addresser.getEmail());
		emailInfo.setPassword(addresser.getPassword());
		return sendEmail(emailInfo);
	}

	public InternetAddress[] toAddress(List<String> address) throws AddressException {
		List<InternetAddress> to = new ArrayList<>();
		for (String add : address) {
			to.add(new InternetAddress(add));//收件人账号
		}
		return to.stream().toArray(InternetAddress[]::new);
	}


}

